package com.cyz.api.aliyunai;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.cyz.api.aliyunai.model.CreateOutPaintingTaskRequest;
import com.cyz.api.aliyunai.model.CreateOutPaintingTaskResponse;
import com.cyz.api.aliyunai.model.GetOutPaintingTaskResponse;
import com.cyz.exception.BusinessException;
import com.cyz.exception.ErrorCode;
import com.cyz.exception.ThrowUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Slf4j
@Component
public class AliYunAiApi {

    @Value("${aliYunAi.apiKey}")
    private String apiKey;

    // 创建扩图任务请求地址
    private static final String CREATE_OUT_PAINTING_TASK_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/out-painting";

    // 获取扩图任务结果请求地址
    private static final String GET_OUT_PAINTING_TASK_URL = "https://dashscope.aliyuncs.com/api/v1/tasks/%s";


    public CreateOutPaintingTaskResponse createOutPaintingTask(CreateOutPaintingTaskRequest createOutPaintingTaskRequest) {

        // 校验参数
        ThrowUtils.throwIf(createOutPaintingTaskRequest == null, ErrorCode.PARAMS_ERROR, "扩图参数不能为空");

        // 获取参数信息
        String model = createOutPaintingTaskRequest.getModel();
        CreateOutPaintingTaskRequest.Input input = createOutPaintingTaskRequest.getInput();
        CreateOutPaintingTaskRequest.Parameters parameters = createOutPaintingTaskRequest.getParameters();

        // 构造创建任务请求

        /*  请求参数如下：
        curl --location --request POST 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/out-painting' \
        --header "Authorization: Bearer $DASHSCOPE_API_KEY" \
        --header 'X-DashScope-Async: enable' \
        --header 'Content-Type: application/json' \
        --data '{
            "model": "image-out-painting",
            "input": {
                "image_url": "http://xxx/image.jpg"
            },
            "parameters":{
                "x_scale":2,
                "y_scale":2,
                "best_quality":false,
                "limit_image_size":true
            }
        }'
         */
        HttpRequest httpRequest = HttpRequest.post(CREATE_OUT_PAINTING_TASK_URL)
                .header("Authorization", "Bearer " + apiKey)
                .header("X-DashScope-Async", "enable")
                .header("Content-Type", " application/json")
                .body(JSONUtil.toJsonStr(createOutPaintingTaskRequest));

        // 处理请求
        try (HttpResponse httpResponse = httpRequest.execute()) {
            if (!httpResponse.isOk()) {
                log.error("AI扩图请求失败" + httpResponse.body());
                System.out.println(apiKey);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "AI扩图请求失败");
            }
            String response = httpResponse.body();
            // 转换成实体类
            CreateOutPaintingTaskResponse createOutPaintingTaskResponse = JSONUtil.toBean(response, CreateOutPaintingTaskResponse.class);

            // 判断任务是否成功
            if (createOutPaintingTaskResponse.getCode() != null) {
                log.error("AI扩图失败，{}", createOutPaintingTaskResponse.getMessage());
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "AI扩图失败，" + createOutPaintingTaskResponse.getMessage());
            }

            // 成功就返回响应对象
            return createOutPaintingTaskResponse;
        }
    }

    public GetOutPaintingTaskResponse getOutPaintingTask(String taskId) {
        // 校验参数
        if (StrUtil.isBlank(taskId)) {
            log.error("taskId为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "获取扩图结果失败");
        }

        // 构造获取结果请求
        /*  获取扩图结果请求参数如下：
            curl -X GET \
            --header "Authorization: Bearer $DASHSCOPE_API_KEY" \
            https://dashscope.aliyuncs.com/api/v1/tasks/86ecf553-d340-4e21-xxxxxxxxx
         */
        HttpRequest httpRequest = HttpRequest.get(String.format(GET_OUT_PAINTING_TASK_URL, taskId))
                .header("Authorization", "Bearer " + apiKey);
        try (HttpResponse httpResponse = httpRequest.execute()) {
            // 判断响应是否成功
            if (!httpResponse.isOk()) {
                log.error("获取任务结果失败，{}", httpResponse.body());
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取扩图结果失败");
            }
            // 将结果转换成实体
            String response = httpResponse.body();
            GetOutPaintingTaskResponse getOutPaintingTaskResponse = JSONUtil.toBean(response, GetOutPaintingTaskResponse.class);

            // 判断结果是否成功
            GetOutPaintingTaskResponse.Output output = getOutPaintingTaskResponse.getOutput();
            if (output.getCode() != null) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR,
                        Objects.equals(output.getMessage(), "the size of input image is too small or to large") ? "图片太小或太大，图像分辨率：不低于512×512像素且不超过4096×4096像素" : "AI接口调用失败，请联系管理员");
            }
            return getOutPaintingTaskResponse;
        }
    }
}
